#region License

/*
  GShield - Game Shield
  Copyright (C) 2006-2007 WaveTech Digital Technologies, Inc.
                                http://www.wtdt.com

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#endregion License

#region Includes

using System.Collections.Generic;
using System.Linq;
using WaveTech.GShield.Data.Collections;

#endregion

namespace WaveTech.GShield.Data
{
	public static class GamesDAO
	{
		#region Get All Games

		public static GameCollection GetAllGames()
		{
			var games = from g in Database.DC.Games
			            select g;

			return (GameCollection) games.ToList();
		}

		#endregion Get All Games

		public static Game GetGameById(int gameId)
		{
			var game = from g in Database.DC.Games
			           where g.Id == gameId
			           select g;

			return game.Single();
		}

		public static Game GetGameByPath(string path)
		{
			var game = from g in Database.DC.Games
			           where g.Path == path
			           select g;

			return game.Single();
		}

		public static Game GetGameByProductNameCompany(string productName, string company)
		{
			var game = from g in Database.DC.Games
			           where g.ProductName == productName && g.Company == company
			           select g;

			return game.Single();
		}

		public static Game GetGameByName(string name)
		{
			var game = from g in Database.DC.Games
			           where g.Name == name
			           select g;

			return game.Single();
		}

		public static void Save(Game game)
		{
			Database.DC.Games.InsertOnSubmit(game);
			Database.DC.SubmitChanges();
		}

		public static List<string> GetGameList()
		{
			var list = from g in Database.DC.Games
			           select g.Name;

			return list.ToList();
		}

		public static void Delete(int gameId)
		{
			var game = from g in Database.DC.Games
			           where g.Id == gameId
			           select g;

			Database.DC.Games.DeleteAllOnSubmit(game);
			Database.DC.SubmitChanges();
		}
	}

	#region Old GamesDAO

	/*
	/// <summary>
	/// Games Data Access Objects
	/// </summary>
	public class GamesDAO
	{
		#region Does Game Exist
		/// <summary>
		/// Checks the Database to see if a game exists by File Path
		/// </summary>
		/// <param name="path">Full path to the games exe</param>
		/// <returns>True if the game exists, else false</returns>
		public bool DoesGameExist(string path)
		{
			if (path == null || path.Length <= 0)
				throw new ArgumentNullException("path");

			Database db;
			DbCommand dbCommand;
			object o;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT Id, [Name], Publisher, Content, Rating, RatingTypes, Platforms, 
																						FileName, Path, InternalName, ProductName, Company, DirectoryName, 
																						DateAdded, WasChecked, DateChecked, NotAGame, [Hash]
																					FROM dbo.Games
																					WHERE (Path = @Path)");

			db.AddInParameter(dbCommand, "@Path", DbType.String, path);

			o = db.ExecuteScalar(dbCommand);

			if (o == null)
				return false;
			else
				return true;
		}

		/// <summary>
		/// Checks the Database to see if a game exists by Product Name and Company
		/// </summary>
		/// <param name="productName">Product Name to check</param>
		/// <param name="company">Company Name to check</param>
		/// <returns>True if the game exists, else false</returns>
		public bool DoesGameExist(string productName, string company)
		{
			if (productName == null || productName.Length <= 0)
				throw new ArgumentNullException("productName");
			else if (company == null || company.Length <= 0)
				throw new ArgumentNullException("company");

			Database db;
			DbCommand dbCommand;
			object o;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT Id, [Name], Publisher, Content, Rating, RatingTypes, Platforms, 
																							FileName, Path, InternalName, ProductName, Company, DirectoryName, 
																							DateAdded, WasChecked, DateChecked, NotAGame, [Hash]
																					FROM dbo.Games
																					WHERE (ProductName = @Name) AND (Company = @Company)");

			db.AddInParameter(dbCommand, "@Name", DbType.String, productName);
			db.AddInParameter(dbCommand, "@Company", DbType.String, company);

			o = db.ExecuteScalar(dbCommand);

			if (o == null)
				return false;
			else
				return true;
		}

		/// <summary>
		/// Checks the Database to see if a game exists by the games Id
		/// </summary>
		/// <param name="id">GameId to lookup</param>
		/// <returns>True if the game exists, else false</returns>
		public bool DoesGameExist(int? id)
		{
			if (id == null)
				throw new ArgumentNullException("id");

			Database db;
			DbCommand dbCommand;
			object o;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT Id, [Name], Publisher, Content, Rating, RatingTypes, Platforms, 
																							FileName, Path, InternalName, ProductName, Company, DirectoryName, 
																							DateAdded, WasChecked, DateChecked, NotAGame, [Hash]
																						FROM dbo.Games
																						WHERE (Id = @Id)");

			db.AddInParameter(dbCommand, "@Id", DbType.Int32, id);

			o = db.ExecuteScalar(dbCommand);

			if (o == null)
				return false;
			else
				return true;
		}
		#endregion Does Game Exist

		#region Get Game
		/// <summary>
		/// Gets a game from the database by it's Id
		/// </summary>
		/// <param name="id">GameId to retrieve game for</param>
		/// <returns>Populated Game Object</returns>
		public Game GetGame(int? id)
		{
			if (id == null)
				throw new ArgumentNullException("id");

			Game g;
			Database db;
			DbCommand dbCommand;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT Id, [Name], Publisher, Content, Rating, RatingTypes, Platforms, 
																							FileName, Path, InternalName, ProductName, Company, DirectoryName, 
																							DateAdded, WasChecked, DateChecked, NotAGame, [Hash]
																						FROM dbo.Games
																						WHERE (Id = @Id)");

			db.AddInParameter(dbCommand, "@Id", DbType.Int32, id);

			g = FillGameObject(db.ExecuteReader(dbCommand));

			return g;
		}

		/// <summary>
		/// Gets a game from the database by it's full path
		/// </summary>
		/// <param name="path">Full Path to game exe</param>
		/// <returns>Populated Game Object</returns>
		public Game GetGame(string path)
		{
			if (path == null || path.Length <= 0)
				throw new ArgumentNullException("path");

			Game g;
			Database db;
			DbCommand dbCommand;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT Id, [Name], Publisher, Content, Rating, RatingTypes, Platforms, 
																						FileName, Path, InternalName, ProductName, Company, DirectoryName, 
																						DateAdded, WasChecked, DateChecked, NotAGame, [Hash]
																					FROM dbo.Games
																					WHERE (Path = @Path)");

			db.AddInParameter(dbCommand, "@Path", DbType.String, path);

			g = FillGameObject(db.ExecuteReader(dbCommand));

			return g;
		}

		/// <summary>
		/// Gets a game from the database by it's name
		/// </summary>
		/// <param name="name">Full name of the game</param>
		/// <returns>Populated Game Object</returns>
		public Game GetGameByName(string name)
		{
			if (name == null || name.Length <= 0)
				throw new ArgumentNullException("name");

			Game g;
			Database db;
			DbCommand dbCommand;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT Id, [Name], Publisher, Content, Rating, RatingTypes, Platforms, 
																							FileName, Path, InternalName, ProductName, Company, DirectoryName, 
																							DateAdded, WasChecked, DateChecked, NotAGame, [Hash]
																					FROM dbo.Games
																					WHERE ([Name] = @Name)");

			db.AddInParameter(dbCommand, "@Name", DbType.String, name);

			g = FillGameObject(db.ExecuteReader(dbCommand));

			return g;
		}

		/// <summary>
		/// Gets a game by Product Name and Company
		/// </summary>
		/// <param name="productName">Product Name of the game</param>
		/// <param name="company">Company of the game</param>
		/// <returns>Populated Game Object</returns>
		public Game GetGame(string productName, string company)
		{
			if (productName == null || productName.Length <= 0)
				throw new ArgumentNullException("productName");
			else if (company == null || company.Length <= 0)
				throw new ArgumentNullException("company");

			Game g;
			Database db;
			DbCommand dbCommand;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT Id, [Name], Publisher, Content, Rating, RatingTypes, Platforms, 
																							FileName, Path, InternalName, ProductName, Company, DirectoryName, 
																							DateAdded, WasChecked, DateChecked, NotAGame, [Hash]
																					FROM dbo.Games
																					WHERE (ProductName = @Name) AND (Company = @Company)");

			db.AddInParameter(dbCommand, "@Name", DbType.String, productName);
			db.AddInParameter(dbCommand, "@Company", DbType.String, company);

			g = FillGameObject(db.ExecuteReader(dbCommand));

			return g;
		}
		#endregion Get Game

		#region Save
		/// <summary>
		/// Saves or Updates a game in the database
		/// </summary>
		/// <param name="game">Populated game object to update or save</param>
		/// <returns>Populated Game Object</returns>
		public Game Save(Game game)
		{
			if (game == null)
				throw new ArgumentNullException("game");

			if (game.Id == null)
				game = Insert(game);
			else
				game = Update(game);

			return game;
		}
		#endregion Save

		#region Insert
		/// <summary>
		/// Inserts a game object to the database
		/// </summary>
		/// <param name="game">Popualted game object to save</param>
		/// <returns>Populated Game Object</returns>
		private Game Insert(Game game)
		{
			if (game == null)
				throw new ArgumentNullException("game");
			else if (game.Id != null)
				throw new ArgumentException("Game.Id must be null to perform an insert.");

			Database db;
			DbCommand dbCommand;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"INSERT INTO [Games]
																						 ([Name]
																						 ,[Publisher]
																						 ,[Content]
																						 ,[Rating]
																						 ,[RatingTypes]
																						 ,[Platforms]
																						 ,[FileName]
																						 ,[Path]
																						 ,[InternalName]
																						 ,[ProductName]
																						 ,[Company]
																						 ,[DirectoryName]
																						 ,[DateAdded]
																						 ,[WasChecked]
																						 ,[DateChecked]
																						 ,[NotAGame]
																						 ,[Hash])
																			 VALUES
																						 (@Name
																						 ,@Publisher
																						 ,@Content
																						 ,@Rating
																						 ,@RatingTypes
																						 ,@Platforms
																						 ,@FileName
																						 ,@Path
																						 ,@InternalName
																						 ,@ProductName
																						 ,@Company
																						 ,@DirectoryName
																						 ,@DateAdded
																						 ,@WasChecked
																						 ,@DateChecked
																						 ,@NotAGame
																						 ,@Hash)
																		
																		SELECT Scope_Identity()");

			db.AddInParameter(dbCommand, "@Name", DbType.String, game.Name);
			db.AddInParameter(dbCommand, "@Publisher", DbType.String, game.Publisher);
			db.AddInParameter(dbCommand, "@Content", DbType.String, game.Content);
			db.AddInParameter(dbCommand, "@Rating", DbType.String, game.Rating);
			db.AddInParameter(dbCommand, "@RatingTypes", DbType.Int32, game.RatingTypes.Value);
			db.AddInParameter(dbCommand, "@Platforms", DbType.String, game.Platforms);
			db.AddInParameter(dbCommand, "@FileName", DbType.String, game.FileName);
			db.AddInParameter(dbCommand, "@Path", DbType.String, game.Path);
			db.AddInParameter(dbCommand, "@InternalName", DbType.String, game.InternalName);
			db.AddInParameter(dbCommand, "@ProductName", DbType.String, game.ProductName);
			db.AddInParameter(dbCommand, "@Company", DbType.String, game.Company);
			db.AddInParameter(dbCommand, "@DirectoryName", DbType.String, game.DirectoryName);
			db.AddInParameter(dbCommand, "@DateAdded", DbType.DateTime, game.DateAdded);
			db.AddInParameter(dbCommand, "@WasChecked", DbType.Boolean, game.WasChecked);
			db.AddInParameter(dbCommand, "@DateChecked", DbType.DateTime, game.DateChecked);
			db.AddInParameter(dbCommand, "@NotAGame", DbType.Boolean, game.NotAGame);
			db.AddInParameter(dbCommand, "@Hash", DbType.String, game.GetHashCode());

			game.Id = int.Parse(db.ExecuteScalar(dbCommand).ToString());

			return game;
		}
		#endregion Insert

		#region Update
		/// <summary>
		/// Updates an existing game object in the database
		/// </summary>
		/// <param name="game">Game object to update</param>
		/// <returns>Copy of the presisted game object</returns>
		private Game Update(Game game)
		{
			if (game == null)
				throw new ArgumentNullException("game");
			else if (game.Id == null)
				throw new ArgumentException("Game.Id must not be null to perform an update.");

			Database db;
			DbCommand dbCommand;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"UPDATE [Games]
																						SET [Name] = @Name
																								,[Publisher] = @Publisher
																								,[Content] = @Content
																								,[Rating] = @Rating
																								,[RatingTypes] = @RatingTypes
																								,[Platforms] = @Platforms
																								,[FileName] = @FileName
																								,[Path] = @Path
																								,[InternalName] = @InternalName
																								,[ProductName] = @ProductName
																								,[Company] = @Company
																								,[DirectoryName] = @DirectoryName
																								,[DateAdded] = @DateAdded
																								,[WasChecked] = @WasChecked
																								,[DateChecked] = @DateChecked
																								,[NotAGame] = @NotAGame
																								,[Hash] = @Hash
																						WHERE (Id = @Id)");

			db.AddInParameter(dbCommand, "@Name", DbType.String, game.Name);
			db.AddInParameter(dbCommand, "@Publisher", DbType.String, game.Publisher);
			db.AddInParameter(dbCommand, "@Content", DbType.String, game.Content);
			db.AddInParameter(dbCommand, "@Rating", DbType.String, game.Rating);
			db.AddInParameter(dbCommand, "@RatingTypes", DbType.Int32, game.RatingTypes.Value);
			db.AddInParameter(dbCommand, "@Platforms", DbType.String, game.Platforms);
			db.AddInParameter(dbCommand, "@FileName", DbType.String, game.FileName);
			db.AddInParameter(dbCommand, "@Path", DbType.String, game.Path);
			db.AddInParameter(dbCommand, "@InternalName", DbType.String, game.InternalName);
			db.AddInParameter(dbCommand, "@ProductName", DbType.String, game.ProductName);
			db.AddInParameter(dbCommand, "@Company", DbType.String, game.Company);
			db.AddInParameter(dbCommand, "@DirectoryName", DbType.String, game.DirectoryName);
			db.AddInParameter(dbCommand, "@DateAdded", DbType.DateTime, game.DateAdded);
			db.AddInParameter(dbCommand, "@WasChecked", DbType.Boolean, game.WasChecked);
			db.AddInParameter(dbCommand, "@DateChecked", DbType.DateTime, game.DateChecked);
			db.AddInParameter(dbCommand, "@NotAGame", DbType.Boolean, game.NotAGame);
			db.AddInParameter(dbCommand, "@Hash", DbType.String, game.GetHashCode());
			db.AddInParameter(dbCommand, "@Id", DbType.Int32, game.Id);

			db.ExecuteNonQuery(dbCommand);

			return game;
		}
		#endregion Update

		#region Delete
		/// <summary>
		/// Deletes a game from the database
		/// </summary>
		/// <param name="id">GameId of the game to delete</param>
		public void Delete(int? id)
		{
			if (id == null)
				throw new ArgumentNullException("id");

			Database db;
			DbCommand dbCommand;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"DELETE
																					FROM dbo.Games
																					WHERE (Id = @Id)");

			db.AddInParameter(dbCommand, "@Id", DbType.Int32, id);

			db.ExecuteScalar(dbCommand);
		}
		#endregion Delete

		#region Get Games List
		/// <summary>
		/// Gets all the game names from the database
		/// </summary>
		/// <returns></returns>
		public string[] GetGamesList()
		{
			Database db;
			DbCommand dbCommand;
			ArrayList lst;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT [Name]
																					 FROM Games");

			lst = new ArrayList();
			IDataReader r = db.ExecuteReader(dbCommand);

			while (r.Read())
			{
				lst.Add(r[0].ToString());
			}

			return (string[])lst.ToArray(typeof(string));
		}
		#endregion Get Games List

		#region Get Games
		/// <summary>
		/// Gets all the games in the system
		/// </summary>
		/// <returns>Filled Collection of Games</returns>
		public GameCollection GetGames()
		{
			Database db;
			DbCommand dbCommand;
			IDataReader reader;
			GameCollection games = null;

			db = DatabaseFactory.CreateDatabase();
			dbCommand = db.GetSqlStringCommand(@"SELECT [Id] ,[Name] ,[Publisher] ,[Content] ,[Rating] ,[RatingTypes] ,[Platforms]
																					,[FileName] ,[Path] ,[InternalName] ,[ProductName] ,[Company] ,[DirectoryName]
																					,[DateAdded] ,[WasChecked] ,[DateChecked] ,[NotAGame] ,[Hash]
																					FROM [GShield].[dbo].[Games]");

			reader = db.ExecuteReader(dbCommand);

			if (reader != null)
			{
				games = new GameCollection();
				Game m_game = FillGameObject(reader);

				while (m_game != null)
				{
					games.Add(m_game);
					m_game = FillGameObject(reader);
				}
			}

			return games;
		}
		#endregion Get Games

		#region Fill Game Object
		/// <summary>
		/// Populates a Game object from a DataReader
		/// </summary>
		/// <param name="reader">DataReader used to populate a game</param>
		/// <returns>Populated game object</returns>
		private Game FillGameObject(IDataReader reader)
		{
			if (reader == null)
				throw new ArgumentNullException("reader");

			Game game = null;

			if (reader.Read())
			{
				game = new Game();

				if (!reader.IsDBNull(reader.GetOrdinal("Id")))
					game.Id = reader.GetInt32(reader.GetOrdinal("Id"));

				if (!reader.IsDBNull(reader.GetOrdinal("Name")))
					game.Name = reader.GetString(reader.GetOrdinal("Name"));

				if (!reader.IsDBNull(reader.GetOrdinal("Publisher")))
					game.Publisher = reader.GetString(reader.GetOrdinal("Publisher"));

				if (!reader.IsDBNull(reader.GetOrdinal("Content")))
					game.Content = reader.GetString(reader.GetOrdinal("Content"));

				if (!reader.IsDBNull(reader.GetOrdinal("Rating")))
					game.Rating = reader.GetString(reader.GetOrdinal("Rating"));

				if (!reader.IsDBNull(reader.GetOrdinal("RatingTypes")))
					game.RatingTypes = reader.GetInt32(reader.GetOrdinal("RatingTypes"));

				if (!reader.IsDBNull(reader.GetOrdinal("Platforms")))
					game.Platforms = reader.GetString(reader.GetOrdinal("Platforms"));

				if (!reader.IsDBNull(reader.GetOrdinal("FileName")))
					game.FileName = reader.GetString(reader.GetOrdinal("FileName"));

				if (!reader.IsDBNull(reader.GetOrdinal("Path")))
					game.Path = reader.GetString(reader.GetOrdinal("Path"));

				if (!reader.IsDBNull(reader.GetOrdinal("InternalName")))
					game.InternalName = reader.GetString(reader.GetOrdinal("InternalName"));

				if (!reader.IsDBNull(reader.GetOrdinal("ProductName")))
					game.ProductName = reader.GetString(reader.GetOrdinal("ProductName"));

				if (!reader.IsDBNull(reader.GetOrdinal("Company")))
					game.Company = reader.GetString(reader.GetOrdinal("Company"));

				if (!reader.IsDBNull(reader.GetOrdinal("DirectoryName")))
					game.DirectoryName = reader.GetString(reader.GetOrdinal("DirectoryName"));

				if (!reader.IsDBNull(reader.GetOrdinal("DateAdded")))
					game.DateAdded = reader.GetDateTime(reader.GetOrdinal("DateAdded"));

				if (!reader.IsDBNull(reader.GetOrdinal("WasChecked")))
					game.WasChecked = reader.GetBoolean(reader.GetOrdinal("WasChecked"));

				if (!reader.IsDBNull(reader.GetOrdinal("DateChecked")))
					game.DateChecked = reader.GetDateTime(reader.GetOrdinal("DateChecked"));

				if (!reader.IsDBNull(reader.GetOrdinal("NotAGame")))
					game.NotAGame = reader.GetBoolean(reader.GetOrdinal("NotAGame"));

				if (!reader.IsDBNull(reader.GetOrdinal("Hash")))
					game.Hash = reader.GetString(reader.GetOrdinal("Hash"));
			}
			return game;
		}
		#endregion Fill Game Object
	}
    */

	#endregion Old GamesDAO
}